package inmobiliaria.frsf.action;

import inmobiliaria.frsf.bo.VentaBO;
import inmobiliaria.frsf.bo.impl.InmuebleBOImpl;
import inmobiliaria.frsf.bo.impl.VentaBOImpl;
import inmobiliaria.frsf.enums.EstadoInmuebleEnum;
import inmobiliaria.frsf.enums.TipoDocumentoEnum;
import inmobiliaria.frsf.enums.TipoInmuebleEnum;
import inmobiliaria.frsf.model.Cliente;
import inmobiliaria.frsf.model.Inmueble;
import inmobiliaria.frsf.model.Persona;
import inmobiliaria.frsf.model.Vendedor;
import inmobiliaria.frsf.model.Venta;
import inmobiliaria.frsf.reports.dto.ReporteVentaDTO;
import inmobiliaria.frsf.reports.utils.GestionReporte;
import inmobiliaria.frsf.reports.utils.ReportData;
import inmobiliaria.frsf.util.DateUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

/**
 * @author Gonzalo
 * 
 */
public class VentaAction extends ActionSupport {

	/**
	 * Serial version ID
	 */
	private static final long serialVersionUID = 5766302492688390944L;

	/**
	 * BO de venta
	 */
	private VentaBO ventaBO = new VentaBOImpl();

	/**
	 * Entidad de venta
	 */
	public Venta venta = new Venta();

	/**
	 * Lista de inmuebles
	 */
	public List<Inmueble> inmuebles = new ArrayList<Inmueble>();

	/**
	 * Lista de clientes
	 */
	public List<Persona> clientes = new ArrayList<Persona>();
	
	/**
	 * Lista los tipos de inmueble
	 */
	public List<TipoInmuebleEnum> tiposInmueble = new ArrayList<TipoInmuebleEnum>();
	
	/**
	 * Monto de venta
	 */
	public Float montoVenta;
	
	/**
	 * Cliente seleccionado
	 */
	public Integer idCliente;
	
	/**
	 * Inmueble seleccionado
	 */
	public Integer inmuebleSeleccionado;

	/**
	 * BO de Inmueble
	 */
	private InmuebleBOImpl inmuebleBO = new InmuebleBOImpl();
	
	/**
	 * Filtros grilla
	 */
	public String idTipoInmueble = "";
	public String barrio = "";
	public String ciudad = "";
	public String precioDesde = "";
	public String precioHasta = "";
	
	/**
	 * Constante para redirección.
	 */
	public static final String HOME = "home";
	public static final String VENTA = "venta";

	@Override
	public String execute() throws Exception {
		return abrirVenta();
	}

	/**
	 * Abre la pantalla de venta
	 * 
	 * @return
	 * @throws Exception
	 */
	public String abrirVenta() throws Exception {
		inicializarGrillaInmuebles();
		this.clientes = ventaBO.searchClientes();
		this.tiposInmueble = TipoInmuebleEnum.getList();
		this.montoVenta = new Float(0);
		ServletActionContext.getRequest().getSession().setAttribute("totalResults", inmuebles.size());
		ServletActionContext.getRequest().getSession().setAttribute("pageSize", 5);
		
		return VENTA;
	}

	/**
	 * Remueve el propietario de la lista de clientes disponible para la compra
	 * 
	 * @return
	 * @throws Exception
	 */
	public String rbClick() throws Exception {
		reestablecerSesion();
		
		for(Inmueble i : inmuebles){
			if(i.getIdInmueble().equals(this.inmuebleSeleccionado)) {
				for(Persona c : clientes){
					if(c.getIdPersona().equals(i.getPropietario().getIdPersona())) {
						clientes.remove(c);
						break;
					}
				}
				break;
			}
		}
		
		return VENTA;
	}
	
	/**
	 * Guarda la venta realizada.
	 * 
	 * @return
	 * @throws Exception
	 */
	public String guardar() throws Exception {
		try{
			reestablecerSesion();
			//Asociamos a la venta el cliente seleccionado
			for(Persona c : clientes){
				if(c.getIdPersona().equals(this.idCliente)) {
					venta.setCliente(c);
					break;
				}
			}
			
			//Asociamos a la venta el inmueble seleccionado
			for(Inmueble i : inmuebles){
				if(i.getIdInmueble().equals(this.inmuebleSeleccionado)) {
					venta.setInmueble(i);
					break;
				}
			}
			
			venta.setVendedor(new Vendedor(0, inmuebles.get(0).getDomicilio(), "Carlos",
					"Gonzales", "15456998", "cacho@gmail.com",
					TipoDocumentoEnum.DNI.getId(), 24567855, Calendar.getInstance()));
			venta.setMonto(this.montoVenta);
			venta.setFecha(Calendar.getInstance());
			ventaBO.guardar(venta);
			
			generarReporteVenta(venta);
			
			ServletActionContext.getRequest().setAttribute("resultado", "OK");
			abrirVenta();
		}
		catch(Exception e)
		{			
			ServletActionContext.getRequest().setAttribute("resultado", "ERROR");
			abrirVenta();
		}
		return VENTA;
	}
	
	/**
	 * Realiza el filtrado de la grilla de propietarios.
	 * 
	 * @return
	 * @throws Exception
	 */
	public String filtrarGrilla() throws Exception {
		
		this.inmuebles = inmuebleBO.searchInmueble(null, idTipoInmueble, EstadoInmuebleEnum.DISPONIBLE.getId().toString(), barrio, ciudad,
				precioDesde, precioHasta);
		this.tiposInmueble = TipoInmuebleEnum.getList();
		this.clientes = ventaBO.searchClientes();
		
		ServletActionContext.getRequest().setAttribute("totalResults", inmuebles.size());
		ServletActionContext.getRequest().setAttribute("pageSize", 5);

		return VENTA;
	}

	/**
	 * Carga la grilla de inmuebles.
	 * 
	 * @return
	 * @throws Exception
	 */
	public void inicializarGrillaInmuebles() throws Exception {
		this.inmuebles = inmuebleBO.searchInmueble(null, idTipoInmueble, EstadoInmuebleEnum.DISPONIBLE.getId().toString(), barrio, ciudad,
				precioDesde, precioHasta);
	}
	
	/**
	 * Reestablece la informacion del formulario
	 * @throws Exception
	 */
	private void reestablecerSesion() throws Exception{
		inicializarGrillaInmuebles();
		this.clientes = ventaBO.searchClientes();
		this.tiposInmueble = TipoInmuebleEnum.getList();
		ServletActionContext.getRequest().setAttribute("totalResults", inmuebles.size());
		ServletActionContext.getRequest().setAttribute("pageSize", 5);
	}

	public String generarReporteVenta(Venta venta) {

		try {

			List<ReporteVentaDTO> ventasDTO = new ArrayList<ReporteVentaDTO>();
			Map<String, String> parameters = new HashMap<String, String>();

			String nombrePropietario = venta.getInmueble().getPropietario().getApellido() + " " +venta.getInmueble().getPropietario().getNombre();
			String nombreVendedor = venta.getVendedor().getApellido() + " " + venta.getVendedor().getNombre();
			String nombreComprador = venta.getCliente().getApellido() + " " + venta.getCliente().getNombre();
			
			ReporteVentaDTO ventaDTO = new ReporteVentaDTO();
			ventaDTO.setCaracteristicasInmueble("Inmueble");
			ventaDTO.setPrecio(venta.getMonto().toString());
			ventaDTO.setPropietario(nombrePropietario);
			ventaDTO.setTipo(venta.getInmueble().getTipoInmuebleString());
			ventaDTO.setVendedor(nombreVendedor);
			ventaDTO.setComprador(nombreComprador);
			ventaDTO.setUbicacionGeografica(venta.getInmueble().getUbicacionGeografica());
			ventasDTO.add(ventaDTO);

			Calendar fecha = Calendar.getInstance();
			String fechaReporte = DateUtils.getFechaEnLetras(fecha);
			parameters.put("fechaReporte", fechaReporte);

			ReportData reportData = new ReportData();
			reportData.setParameters(parameters);
			reportData.setDataSource(new JRBeanCollectionDataSource(ventasDTO));
			reportData.setReportName("documentoVta.jasper");

			GestionReporte.generarReporte(reportData);

			return "OK";

		} catch (Exception e) {
			e.printStackTrace();
			return "ERROR";
		}

	}

	/**
	 * @return the ventaBO
	 */
	public VentaBO getVentaBO() {
		return ventaBO;
	}

	/**
	 * @param ventaBO
	 *            the ventaBO to set
	 */
	public void setVentaBO(VentaBO ventaBO) {
		this.ventaBO = ventaBO;
	}


	/**
	 * @return the clientes
	 */
	public List<Persona> getClientes() {
		return clientes;
	}


	/**
	 * @param clientes the clientes to set
	 */
	public void setClientes(List<Persona> clientes) {
		this.clientes = clientes;
	}


	/**
	 * @return the monto
	 */
	public Float getMontoVenta() {
		return montoVenta;
	}


	/**
	 * @param monto the monto to set
	 */
	public void setMontoVenta(Float montoVenta) {
		this.montoVenta = montoVenta;
	}


	/**
	 * @return the idCliente
	 */
	public Integer getIdCliente() {
		return idCliente;
	}


	/**
	 * @param idCliente the idCliente to set
	 */
	public void setIdCliente(Integer idCliente) {
		this.idCliente = idCliente;
	}


	/**
	 * @return the inmuebleSeleccionado
	 */
	public Integer getInmuebleSeleccionado() {
		return inmuebleSeleccionado;
	}


	/**
	 * @param inmuebleSeleccionado
	 *            the inmuebleSeleccionado to set
	 */
	public void setInmuebleSeleccionado(Integer inmuebleSeleccionado) {
		this.inmuebleSeleccionado = inmuebleSeleccionado;
	}

	/**
	 * @return the idTipoInmueble
	 */
	public String getIdTipoInmueble() {
		return idTipoInmueble;
	}

	/**
	 * @param idTipoInmueble
	 *            the idTipoInmueble to set
	 */
	public void setIdTipoInmueble(String idTipoInmueble) {
		this.idTipoInmueble = idTipoInmueble;
	}

	/**
	 * @return the barrio
	 */
	public String getBarrio() {
		return barrio;
	}

	/**
	 * @param barrio
	 *            the barrio to set
	 */
	public void setBarrio(String barrio) {
		this.barrio = barrio;
	}

	/**
	 * @return the ciudad
	 */
	public String getCiudad() {
		return ciudad;
	}

	/**
	 * @param ciudad
	 *            the ciudad to set
	 */
	public void setCiudad(String ciudad) {
		this.ciudad = ciudad;
	}

	/**
	 * @return the precioDesde
	 */
	public String getPrecioDesde() {
		return precioDesde;
	}

	/**
	 * @param precioDesde
	 *            the precioDesde to set
	 */
	public void setPrecioDesde(String precioDesde) {
		this.precioDesde = precioDesde;
	}

	/**
	 * @return the precioHasta
	 */
	public String getPrecioHasta() {
		return precioHasta;
	}

	/**
	 * @param precioHasta
	 *            the precioHasta to set
	 */
	public void setPrecioHasta(String precioHasta) {
		this.precioHasta = precioHasta;
	}

	/**
	 * @return the tiposInmueble
	 */
	public List<TipoInmuebleEnum> getTiposInmueble() {
		return tiposInmueble;
	}

	/**
	 * @param tiposInmueble
	 *            the tiposInmueble to set
	 */
	public void setTiposInmueble(List<TipoInmuebleEnum> tiposInmueble) {
		this.tiposInmueble = tiposInmueble;
	}
}
